import {
  createConversationAPI,
  sendMessageAPI,
  getMessagesAPI,
  sendAttachmentAPI,
  toggleTyping,
  setUserLastSeenAt,
  toggleStatus
} from '../../../api/conversation'

import { createTemporaryMessage, getNonDeletedMessages } from './helpers'

export const actions = {
  createConversation: async({ commit, dispatch }, params) => {
    commit('setConversationUIFlag', { isCreating: true })
    try {
      const { data } = await createConversationAPI(params)
      const { messages } = data
      const [message = {}] = messages
      if (message && message.id) {
        // if create conversation without message
        commit('pushMessageToConversation', message)
      }
      dispatch('conversationAttributes/getAttributes', {}, { root: true })
    } catch (error) {
      // Ignore error
    } finally {
      commit('setConversationUIFlag', { isCreating: false })
    }
  },
  sendMessage: async({ dispatch }, params) => {
    const { content } = params
    const message = createTemporaryMessage({ content })

    dispatch('sendMessageWithData', message)
  },
  sendMessageWithData: async({ commit }, message) => {
    const { id, content, meta = {}} = message

    commit('pushMessageToConversation', message)
    commit('updateMessageMeta', { id, meta: { ...meta, error: '' }})
    try {
      const { data } = await sendMessageAPI(content)

      commit('deleteMessage', message.id)
      commit('pushMessageToConversation', { ...data, status: 'sent' })
    } catch (error) {
      commit('pushMessageToConversation', { ...message, status: 'failed' })
      commit('updateMessageMeta', {
        id,
        meta: { ...meta, error: '' }
      })
    }
  },

  sendAttachment: async({ commit }, params) => {
    const {
      attachment: { thumbUrl, fileType },
      meta = {}
    } = params
    const attachment = {
      thumb_url: thumbUrl,
      data_url: thumbUrl,
      file_type: fileType,
      status: 'inProgress'
    }
    const tempMessage = createTemporaryMessage({
      attachments: [attachment]
    })
    commit('pushMessageToConversation', tempMessage)
    try {
      const { data } = await sendAttachmentAPI(params)
      commit('updateAttachmentMessageStatus', {
        message: data,
        tempId: tempMessage.id
      })
      commit('pushMessageToConversation', { ...data, status: 'sent' })
    } catch (error) {
      commit('pushMessageToConversation', { ...tempMessage, status: 'failed' })
      commit('updateMessageMeta', {
        id: tempMessage.id,
        meta: { ...meta, error: '' }
      })
      // Show error
    }
  },
  fetchOldConversations: async({ commit }, { before } = {}) => {
    try {
      commit('setConversationListLoading', true)
      const {
        data: { payload, meta }
      } = await getMessagesAPI({ before })
      const { contactLastSeenAt: lastSeen } = meta
      const formattedMessages = getNonDeletedMessages({ messages: payload })
      commit('conversation/setMetaUserLastSeenAt', lastSeen, { root: true })
      commit('setMessagesInConversation', formattedMessages)
      commit('setConversationListLoading', false)
    } catch (error) {
      commit('setConversationListLoading', false)
    }
  },

  clearConversations: ({ commit }) => {
    commit('clearConversations')
  },

  addOrUpdateMessage: async({ commit }, data) => {
    const { id, contentAttributes } = data
    if (contentAttributes && contentAttributes.deleted) {
      commit('deleteMessage', id)
      return
    }
    commit('pushMessageToConversation', data)
  },

  toggleAgentTyping({ commit }, data) {
    commit('toggleAgentTypingStatus', data)
  },

  toggleUserTyping: async(_, data) => {
    try {
      await toggleTyping(data)
    } catch (error) {
      // IgnoreError
    }
  },

  setUserLastSeen: async({ commit, getters: appGetters }) => {
    if (!appGetters.getConversationSize) {
      return
    }

    const lastSeen = Date.now() / 1000
    try {
      commit('setMetaUserLastSeenAt', lastSeen)
      await setUserLastSeenAt({ lastSeen })
    } catch (error) {
      // IgnoreError
    }
  },

  resolveConversation: async() => {
    await toggleStatus()
  }
}
